package run.bottle.urp.service.impl;

import org.springframework.stereotype.Service;
import run.bottle.urp.model.po.Permission;
import run.bottle.urp.model.po.Role;
import run.bottle.urp.model.po.RolePermission;
import run.bottle.urp.repository.PermissionRepo;
import run.bottle.urp.repository.RolePermissionRepo;
import run.bottle.urp.repository.RoleRepo;
import run.bottle.urp.service.PermissionService;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author liyc
 * @date 2022-04-04
 */
@Service
public class PermissionServiceImpl implements PermissionService {

    private final RoleRepo roleRepo;
    private final PermissionRepo permissionRepo;
    private final RolePermissionRepo rolePermissionRepo;

    public PermissionServiceImpl(RoleRepo roleRepo, PermissionRepo permissionRepo, RolePermissionRepo rolePermissionRepo) {
        this.roleRepo = roleRepo;
        this.permissionRepo = permissionRepo;
        this.rolePermissionRepo = rolePermissionRepo;
    }

    @Override
    public void save(Permission permission) {
        permissionRepo.save(permission);
    }

    @Override
    public void addPermissionToRole(String resourceId, String roleName) {
        Role role = roleRepo.findByRoleName(roleName);
        Permission permission = permissionRepo.findByResourceKey(resourceId);
        if (role != null && permission != null) {
            rolePermissionRepo.save(new RolePermission(null, role.getId(), permission.getId()));
        }
    }

    @Override
    public List<Permission> findByRoleIds(List<Long> roleIds) {
        List<RolePermission> rolePermissions = rolePermissionRepo.findByRoleIdIn(roleIds);
        List<Long> permissionIds = rolePermissions.stream().map(RolePermission::getPermissionId).collect(Collectors.toList());
        List<Permission> permissions = permissionRepo.findByIdIn(permissionIds);
        permissions.sort(Comparator.comparingInt(Permission::getResourceOrder));
        return permissions;
    }

    @Override
    public Map<Long, List<Permission>> findRolePermissionByRoleId(List<Long> roleIds) {
        List<RolePermission> rolePermissions = rolePermissionRepo.findByRoleIdIn(roleIds);
        List<Long> permissionIds = rolePermissions.stream().map(RolePermission::getPermissionId).collect(Collectors.toList());
        List<Permission> permissions = permissionRepo.findByIdIn(permissionIds);
        Map<Long, List<Permission>> rolePermissionMap = new HashMap<>();
        Map<Long, Permission> permissionMap = permissions.stream().collect(Collectors.toMap(Permission::getId, p -> p));
        for (RolePermission rolePermission : rolePermissions) {
            Permission permission = permissionMap.get(rolePermission.getPermissionId());
            List<Permission> permissionList = rolePermissionMap.get(rolePermission.getRoleId());
            if (permissionList == null) {
                permissionList = Collections.singletonList(permission);
            }
            permissionList.sort(Comparator.comparingInt(Permission::getResourceOrder));
            rolePermissionMap.put(rolePermission.getRoleId(), permissionList);
        }
        return rolePermissionMap;
    }


}
